home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 June / PCWorld_2007-06_cd.bin / temacd / wikipad / WikidPad-1.9beta2.exe / {app} / extensions / MimeTexCGIBridge.py < prev    next >
Text File  |  2006-12-11  |  7KB  |  207 lines

  1. import os, urllib
  2. from subprocess import list2cmdline
  3.  
  4. import wx
  5.  
  6. from pwiki.StringOps import mbcsEnc
  7.  
  8. WIKIDPAD_PLUGIN = (("InsertionByKey", 1), ("Options", 1))
  9.  
  10. def describeInsertionKeys(ver, app):
  11.     """
  12.     API function for "InsertionByKey" plugins
  13.     Returns a sequence of tuples describing the supported
  14.     insertion keys. Each tuple has the form (insKey, exportTypes, handlerFactory)
  15.     where insKey is the insertion key handled, exportTypes is a sequence of
  16.     strings describing the supported export types and handlerFactory is
  17.     a factory function (normally a class) taking the wxApp object as
  18.     parameter and returning a handler object fulfilling the protocol
  19.     for "insertion by key" (see EqnHandler as example).
  20.  
  21.     ver -- API version (can only be 1 currently)
  22.     app -- wxApp object
  23.     """
  24.     return ((u"eqn", ("html_single", "html_previewWX", "html_preview",
  25.             "html_multi"), EqnHandler),)
  26.  
  27.  
  28. class EqnHandler:
  29.     """
  30.     Class fulfilling the "insertion by key" protocol.
  31.     """
  32.     def __init__(self, app):
  33.         self.app = app
  34.         self.mimetexExe = None
  35.         
  36.     def taskStart(self, exporter, exportType):
  37.         """
  38.         This is called before any call to createContent() during an
  39.         export task.
  40.         An export task can be a single HTML page for
  41.         preview or a single page or a set of pages for export.
  42.         exporter -- Exporter object calling the handler
  43.         exportType -- string describing the export type
  44.         
  45.         Calls to createContent() will only happen after a 
  46.         call to taskStart() and before the call to taskEnd()
  47.         """
  48.         # Find MimeTeX executable by configuration setting
  49.         self.mimetexExe = self.app.getGlobalConfig().get("main",
  50.                 "plugin_mimeTex_exePath", "")
  51.  
  52.         
  53.     def taskEnd(self):
  54.         """
  55.         Called after export task ended and after the last call to
  56.         createContent().
  57.         """
  58.         pass
  59.  
  60.  
  61.     def createContent(self, exporter, exportType, insToken):
  62.         """
  63.         Handle an insertion and create the appropriate content.
  64.  
  65.         exporter -- Exporter object calling the handler
  66.         exportType -- string describing the export type
  67.         insToken -- insertion token to create content for (see also 
  68.                 PageAst.Insertion)
  69.  
  70.         An insertion token has the following member variables:
  71.             key: insertion key (unistring)
  72.             value: value of an insertion (unistring)
  73.             appendices: sequence of strings with the appendices
  74.  
  75.         Meaning and type of return value is solely defined by the type
  76.         of the calling exporter.
  77.         
  78.         For HtmlXmlExporter a unistring is returned with the HTML code
  79.         to insert instead of the insertion.        
  80.         """
  81.         bstr = urllib.quote(mbcsEnc(insToken.value, "replace")[0])
  82.  
  83.         if not bstr:
  84.             # Nothing in, nothing out
  85.             return u""
  86.         
  87.         if self.mimetexExe == "":
  88.             # No path to MimeTeX executable -> show message
  89.             return "<pre>[Please set path to MimeTeX executable]</pre>"
  90.  
  91.         # Prepare CGI environment. MimeTeX needs only "QUERY_STRING" environment
  92.         # variable
  93.         os.environ["QUERY_STRING"] = bstr
  94.  
  95.         cmdline = list2cmdline((self.mimetexExe,))
  96.  
  97.         # Run MimeTeX process
  98.         childIn, childOut = os.popen2(cmdline, "b")
  99.  
  100.         # Read stdout of process entirely
  101.         response = childOut.read()
  102.  
  103.         # Cut off HTTP header (may need changes for non-Windows OS)
  104.         try:
  105.             response = response[(response.index("\n\n") + 2):]
  106.         except ValueError:
  107.             return "<pre>[Invalid response from MimeTeX]</pre>"
  108.  
  109.         # Get exporters temporary file set (manages creation and deletion of
  110.         # temporary files)
  111.         tfs = exporter.getTempFileSet()
  112.         
  113.         # Create .gif file out of returned data and retrieve URL for the file
  114.         pythonUrl = (exportType != "html_previewWX")
  115.         url = tfs.createTempUrl(response, ".gif", pythonUrl=pythonUrl)
  116.  
  117.         # Return appropriate HTML code for the image
  118.         if exportType == "html_previewWX":
  119.             # Workaround for internal HTML renderer
  120.             return u'<img src="%s" border="0" align="bottom" /> ' % url
  121.         else:
  122.             return u'<img src="%s" border="0" align="bottom" />' % url
  123.  
  124.  
  125.     def getExtraFeatures(self):
  126.         """
  127.         Returns a list of bytestrings describing additional features supported
  128.         by the plugin. Currently not specified further.
  129.         """
  130.         return ()
  131.  
  132.  
  133.  
  134.  
  135. def registerOptions(ver, app):
  136.     """
  137.     API function for "Options" plugins
  138.     Register configuration options and their GUI presentation
  139.     ver -- API version (can only be 1 currently)
  140.     app -- wxApp object
  141.     """
  142.     # Register option
  143.     app.getDefaultGlobalConfigDict()[("main", "plugin_mimeTex_exePath")] = u""
  144.     # Register panel in options dialog
  145.     app.addOptionsDlgPanel(MimeTexOptionsPanel, u"  MimeTeX")
  146.  
  147.  
  148. class MimeTexOptionsPanel(wx.Panel):
  149.     def __init__(self, parent, optionsDlg, app):
  150.         """
  151.         Called when "Options" dialog is opened to show the panel.
  152.         Transfer here all options from the configuration file into the
  153.         text fields, check boxes, ...
  154.         """
  155.         wx.Panel.__init__(self, parent)
  156.         self.app = app
  157.         
  158.         pt = self.app.getGlobalConfig().get("main", "plugin_mimeTex_exePath", "")
  159.         
  160.         self.tfPath = wx.TextCtrl(self, -1, pt)
  161.  
  162.         mainsizer = wx.BoxSizer(wx.VERTICAL)
  163.  
  164.         inputsizer = wx.BoxSizer(wx.HORIZONTAL)
  165.         inputsizer.Add(wx.StaticText(self, -1, "Path to MimeTeX:"), 0,
  166.                 wx.ALL | wx.EXPAND, 5)
  167.         inputsizer.Add(self.tfPath, 1, wx.ALL | wx.EXPAND, 5)
  168.         mainsizer.Add(inputsizer, 0, wx.EXPAND)
  169.         
  170.         self.SetSizer(mainsizer)
  171.         self.Fit()
  172.  
  173.     def setVisible(self, vis):
  174.         """
  175.         Called when panel is shown or hidden. The actual wxWindow.Show()
  176.         function is called automatically.
  177.         
  178.         If a panel is visible and becomes invisible because another panel is
  179.         selected, the plugin can veto by returning False.
  180.         When becoming visible, the return value is ignored.
  181.         """
  182.         return True
  183.  
  184.     def checkOk(self):
  185.         """
  186.         Called when "OK" is pressed in dialog. The plugin should check here if
  187.         all input values are valid. If not, it should return False, then the
  188.         Options dialog automatically shows this panel.
  189.         
  190.         There should be a visual indication about what is wrong (e.g. red
  191.         background in text field). Be sure to reset the visual indication
  192.         if field is valid again.
  193.         """
  194.         return True
  195.  
  196.     def handleOk(self):
  197.         """
  198.         This is called if checkOk() returned True for all panels. Transfer here
  199.         all values from text fields, checkboxes, ... into the configuration
  200.         file.
  201.         """
  202.         pt = self.tfPath.GetValue()
  203.         
  204.         self.app.getGlobalConfig().set("main", "plugin_mimeTex_exePath", pt)
  205.  
  206.  
  207.